home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir34 / bdc.zip / MGCOPY.C < prev    next >
C/C++ Source or Header  |  1993-05-29  |  9KB  |  296 lines

  1. /****************************************************************************
  2.  *                                                                          *
  3.                MicroGenesis BULK Disk Copier
  4.             Copyright 1993 by MicroGenesis Software
  5.  
  6. Original version in May of '93
  7.  
  8. (email, in order of pref.)
  9.  CIS:76476,1701
  10.  AOL:JeffH66
  11.  DELPHI:HEATONJ
  12.  BIX: JHEATON
  13.  
  14.  MicroGenesis Software
  15.  P.O. Box 25534
  16.  St. Louis, MO 63125
  17.  (314) 638-2506
  18.  (314) 638-1731 FAX
  19.  
  20.  This source code may be distributed and modified freely.  All I ask is that
  21.  this message(inside the two **** lines remain).  It is okay to add
  22.  additional lines after here crediting whoever may modify this code.  This
  23.  code may be used in any work: public,private,comercial or shareware.  If
  24.  you do use it in some sort of product all I require is that you inform
  25.  me that you will be using it(by fax, email, us-mail, however).
  26.  
  27.  Some of this source code is VERY dangerous!  There are routines in here
  28.  designed to format/write directly to the disk surface.  The exact same
  29.  routines are used to write to your hard disk drive.  This code as is will
  30.  not write to your hard disk drive, but be CAREFUL when you modify
  31.  certian numbers or you may find yourself turning your hard drive into a
  32.  1.44meg floppy look-a-like!(I am not sure what would happen actually, by
  33.  some amazing quirk, I never inverted the numbers and killed my hard drive,
  34.  and loosing 200meg of info is not much of a fun "experiment".
  35.  
  36.  SO as a result if you use this source code, and reformat your hard drive
  37.  or destroy it in some fassion I am not responsable.  I provide no warranty
  38.  for this product of any sort.  Use it at your own risk.  Use it only on
  39.  A: and B: like it was designed for!
  40.  
  41.  A really easy modification of this source code would allow you to create a
  42.  sort of a DISKCOPY for hard drives(even of different sizes).  This source
  43.  code is not designed to do this, but it would make for an interesting mod.
  44.  If you need any advice on this EMAIL me.
  45.  
  46.  Why did I write this program?  Two reasons.  The first version just to see
  47.  if I could still access drives direcly like the good old 8-bit computer
  48.  days.  Second.  This will form the backbone of a background disk duplication
  49.  program I am working on.  I released the code because I couldnt find public
  50.  info on alot of this stuff.
  51.  
  52.  Jeff Heaton, MicroGenesis Software
  53.  
  54.  By the way, the order form is for our other products.  You dont need to
  55.  pay for this one:)
  56.  
  57.  *                                                                          *
  58.  ****************************************************************************/
  59.  
  60. #include <alloc.h>
  61. #include <bios.h>
  62. #include <ctype.h>
  63. #include <dir.h>
  64. #include <dos.h>
  65. #include <io.h>
  66. #include <fcntl.h>
  67. #include <stdio.h>
  68. #include <stdlib.h>
  69. #include <conio.h>
  70.  
  71. #define FALSE    0
  72. #define TRUE    (!FALSE)
  73.  
  74. #define SECTORSIZE    512
  75.  
  76. // BIOS Int13 services we make use of
  77. #define    RESET    0
  78. #define    LAST    1
  79. #define    READ    2
  80. #define    WRITE    3
  81. #define    VERIFY    4
  82. #define    FORMAT    5
  83.  
  84. int density;// How many sectors are in a track
  85.  
  86.  
  87. void msg(char (*s))
  88. {
  89.     printf("%s\n", s);
  90.     _exit(1);
  91. }
  92.  
  93. // Identify the error code with a real error message.
  94. void Error(int (status))
  95. {
  96.     switch (status)
  97.         {
  98. //        case 0x00:msg("Operation Successful");                break;
  99.         case 0x01:msg("Bad command");                    break;
  100.         case 0x02:msg("Address mark not found");            break;
  101.         case 0x03:msg("Attempt to write on write-protected disk");    break;
  102.         case 0x04:msg("Sector not found");                break;
  103.         case 0x05:msg("Reset failed (hard disk)");            break;
  104. //        case 0x06:msg("Disk changed since last operation");        break;
  105.         case 0x07:msg("Drive parameter activity failed");        break;
  106.         case 0x08:msg("DMA overrun");                    break;
  107.         case 0x09:msg("Attempt to DMA across 64K boundary");        break;
  108.         case 0x0A:msg("Bad sector detected");                break;
  109.         case 0x0B:msg("Bad track detected");                break;
  110.         case 0x0C:msg("Unsupported track");                break;
  111.         case 0x10:msg("Bad CRC/ECC on disk read");            break;
  112.         case 0x11:msg("CRC/ECC corrected data error");            break;
  113.         case 0x20:msg("Controller has failed");                break;
  114.         case 0x40:msg("Seek operation failed");                break;
  115.         case 0x80:msg("Attachment failed to respond");            break;
  116.         case 0xAA:msg("Drive not ready (hard disk only");        break;
  117.         case 0xBB:msg("Undefined error occurred (hard disk only)");    break;
  118.         case 0xCC:msg("Write fault occurred");                break;
  119.         case 0xE0:msg("Status error");                    break;
  120.         case 0xFF:msg("Sense operation failed");            break;
  121.         default:return;
  122.         }
  123.     _exit(1);
  124. }
  125.  
  126. // Identify what kind of diskette is installed in the specified drive.
  127. // Return the number of sectors per track assumed as follows:
  128. // 9    -    360 K and 720 K 5.25".
  129. //15    -    1.2 M HD    5.25".
  130. //18    -    1.44 M        3.5".
  131. int nsects(int drive)
  132. {
  133. static    int    nsect[] = {18, 15, 9};
  134. char    *buffer;
  135. int    i, status;
  136.  
  137. // Read sector 1, head 0, track 0 to get the BIOS running.
  138.     buffer = (char *)malloc(SECTORSIZE);
  139.     biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
  140.     status = biosdisk(READ, drive, 0, 10, 1, 1, buffer);
  141.     if (status == 0x06)            // Door signal change?
  142.         status = biosdisk(READ, drive, 0, 0, 1, 1, buffer);
  143.     for (i=0; i < sizeof(nsect)/sizeof(int); ++i)
  144.         {
  145.         biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
  146.         status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
  147.         if (status == 0x06)
  148.             status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
  149.         if (status == 0x00) break;
  150.         }
  151.     if (i == sizeof(nsect)/sizeof(int))
  152.         {
  153.         msg("Can't figure out how many sectors/track for this diskette.");
  154.         }
  155.     free(buffer);
  156.     return(nsect[i]);
  157. }
  158.  
  159.  
  160. // Used to format a disk(a track at a time)
  161. // This only formats the track to the point that we can write to it.
  162. // If you would run format_track on each track of a disk the disk would
  163. // NOT be usable.  It would, however, be ready to be copied to.
  164. //
  165. // Using this on your hard drive(drive 2 or higher) would not really be
  166. // a good idea!  Infact the routine refuses to do so.
  167. void format_track(int drive,int track)
  168. {
  169. struct FORMAT_ARRAY
  170. {
  171.     char track,head,sector,bytes;
  172. } array[30];
  173. union REGS r;
  174. struct SREGS s;
  175. int i;
  176. int head;
  177.  
  178.     if( (drive>1) )// DONT EVEN THINK OF FORMATING THE HD!
  179.         return;
  180.  
  181.     for(head=0;head<=1;head++)
  182.         {
  183.         for(i=0;i<density;i++)
  184.             {
  185.             array[i].track=track;
  186.             array[i].head=head;
  187.             array[i].sector=i+1;
  188.             array[i].bytes=2;
  189.             }
  190.  
  191.         Error(biosdisk(FORMAT,drive,head,track,1,density,array));
  192.         }
  193. }
  194.  
  195. void main(void)
  196. {
  197. char str[80];
  198. char *buffer, *pbuf;
  199. int  drive, head, track, status, buflength, ns;
  200. FILE *fp;
  201. union REGS r;
  202. long free;
  203. int tracks;
  204.  
  205.     puts("MicroGenesis BULK Disk Copier, Copyright 1993 by MicroGenesis Software\n");
  206.  
  207.     if( (fp=fopen("fc.$$$","wb"))==NULL)
  208.         {
  209.         perror("FC.$$$");
  210.         exit(1);
  211.         }
  212.  
  213.     printf("Enter source drive(A or B): ");
  214.     gets(str);
  215.  
  216.     if(!*str)
  217.         exit(0);
  218.  
  219.     drive = *str;
  220.     drive = (islower(drive) ? toupper(drive) : drive) - 'A';
  221.  
  222.     printf("Please the source disk into ");
  223.     printf("drive %c: and press -ENTER- :", drive + 'A');
  224.     getch();
  225.  
  226.     if(drive>1)
  227.         {
  228.         printf("Cant use this on hard drives!\r");
  229.         return;
  230.         }
  231.  
  232.  
  233. // Determine number of sectors per track and allocate buffers.
  234.  
  235.     density = nsects(drive);
  236.     buflength = density * SECTORSIZE;
  237.     buffer = (char *)malloc(buflength);
  238.  
  239.     r.h.ah=0x1c;
  240.     r.h.dl=1;
  241.     int86(0x21,&r,&r);
  242.  
  243.     tracks=(r.h.al*r.x.dx);
  244.     tracks=tracks/density;
  245.     tracks=tracks/2;
  246.  
  247. // Start writing data to diskette until there is no more data to write.
  248.  
  249.     printf("\n\n\nPreparing to copy disk:\n");
  250.     printf("%i tracks, %i sectors per track\n",tracks,density);
  251.  
  252.  
  253.     head = track = 0;
  254.  
  255.     for(track=0;track<=tracks;track++)
  256.         {
  257.         for(head=0;head<=1;head++)
  258.             {
  259.                 Error(biosdisk(READ, drive, head, track,1, density, pbuf));
  260.                 fwrite(pbuf,512,density,fp);
  261.                 printf("Track: %i, Head: %i\r",track,head);
  262.             }
  263.         }
  264.  
  265.     for(;;)
  266.         {
  267.         printf("\n\nPlease the destination disk into ");
  268.         printf("drive %c: and press -ENTER- :", drive + 'A');
  269.         getch();
  270.         putch('\n');
  271.  
  272.         fclose(fp);
  273.         fp=fopen("FC.$$$","rb");
  274.         for(track=0;track<=tracks;track++)
  275.             {
  276.             format_track(drive,track);
  277.             for(head=0;head<=1;head++)
  278.                 {
  279.                 fread(pbuf,512,density,fp);
  280.                 Error(biosdisk(WRITE, drive, head, track,1, density, pbuf));
  281.                 printf("Track: %i, Sector: %i, Head: %i\r",track,0,head);
  282.                 }
  283.             }
  284.  
  285.         printf("\nDone.\n");
  286.         biosdisk(2, drive, 0, 0, 1, 1, buffer);        /* Retract head    */
  287.         fclose(fp);
  288.  
  289.         printf("Make another copy of this disk(Y/N)");
  290.         if(toupper(getch())=='N')
  291.             break;
  292.  
  293.         }
  294.     unlink("FC.$$$");
  295. }    /* end main */
  296.